// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package javascript

//
//import (
//	"context"
//	"sync"
//	"testing"
//	"time"
//
//	"github.com/elastic/beats/v7/libbeat/beat"
//	"github.com/elastic/beats/v7/libbeat/common"
//	"github.com/elastic/beats/v7/libbeat/logp"
//
//	"github.com/stretchr/testify/assert"
//)
//
//func TestSessionTagOnException(t *testing.T) {
//	const script = `throw "this tags the event";`
//
//	p, err := NewFromConfig(Config{
//		Source:         header + script + footer,
//		TagOnException: defaultConfig().TagOnException,
//	}, nil)
//	if err != nil {
//		t.Fatal(err)
//	}
//
//	evt, err := p.Run(testEvent())
//	assert.Error(t, err)
//
//	tags, _ := evt.GetValue("tags")
//	assert.Equal(t, []string{"_js_exception"}, tags)
//}
//
//func TestSessionScriptParams(t *testing.T) {
//	t.Run("register method is optional", func(t *testing.T) {
//		_, err := NewFromConfig(Config{
//			Source: header + footer,
//		}, nil)
//		if err != nil {
//			t.Fatal(err)
//		}
//	})
//
//	t.Run("register required for params", func(t *testing.T) {
//		_, err := NewFromConfig(Config{
//			Source: header + footer,
//			Params: map[string]interface{}{
//				"threshold": 42,
//			},
//		}, nil)
//		if assert.Error(t, err) {
//			assert.Contains(t, err.Error(), "params were provided")
//		}
//	})
//
//	t.Run("register params", func(t *testing.T) {
//		const script = `
//			function register(params) {
//				if (params["threshold"] !== 42) {
//					throw "invalid threshold";
//				}
//			}
//
//			function process(event) {}
//		`
//		_, err := NewFromConfig(Config{
//			Source: script,
//			Params: map[string]interface{}{
//				"threshold": 42,
//			},
//		}, nil)
//		assert.NoError(t, err)
//	})
//}
//
//func TestSessionTestFunction(t *testing.T) {
//	const script = `
//		var fail = false;
//
//		function register(params) {
//			fail = params["fail"];
//		}
//
//		function process(event) {
//			if (fail) {
//				throw "intentional failure";
//			}
//			event.Put("hello", "world");
// 			return event;
//		}
//
//		function test() {
//			var event = process(new Event({"hello": "earth"}));
//
//			if (event.fields.hello !== "world") {
//				throw "invalid hello world";
// 			}
//		}
//	`
//
//	t.Run("test method is optional", func(t *testing.T) {
//		_, err := NewFromConfig(Config{
//			Source: header + footer,
//		}, nil)
//		if err != nil {
//			t.Fatal(err)
//		}
//	})
//
//	t.Run("test success", func(t *testing.T) {
//		_, err := NewFromConfig(Config{
//			Source: script,
//			Params: map[string]interface{}{
//				"fail": false,
//			},
//		}, nil)
//		assert.NoError(t, err)
//	})
//
//	t.Run("test failure", func(t *testing.T) {
//		_, err := NewFromConfig(Config{
//			Source: script,
//			Params: map[string]interface{}{
//				"fail": true,
//			},
//		}, nil)
//		assert.Error(t, err)
//	})
//}
//
//func TestSessionTimeout(t *testing.T) {
//	logp.TestingSetup()
//
//	const runawayLoop = `
//		while (!evt.fields.stop) {
//			evt.Put("hello", "world");
//		}
//    `
//
//	p, err := NewFromConfig(Config{
//		Source:         header + runawayLoop + footer,
//		Timeout:        500 * time.Millisecond,
//		TagOnException: "_js_exception",
//	}, nil)
//	if err != nil {
//		t.Fatal(err)
//	}
//
//	evt := &beat.Event{
//		Fields: common.MapStr{
//			"stop": false,
//		},
//	}
//
//	// Execute and expect a timeout.
//	evt, err = p.Run(evt)
//	if assert.Error(t, err) {
//		assert.Contains(t, err.Error(), timeoutError)
//
//		tags, _ := evt.GetValue("tags")
//		assert.Equal(t, []string{"_js_exception"}, tags)
//
//		errorMessage, _ := evt.GetValue("error.message")
//		assert.Contains(t, errorMessage, timeoutError)
//	}
//
//	// Verify that any internal runtime interrupt state has been cleared.
//	evt.PutValue("stop", true)
//	_, err = p.Run(evt)
//	assert.NoError(t, err)
//}
//
//func TestSessionParallel(t *testing.T) {
//	const script = `
//		evt.Put("host.name", "workstation");
//    `
//
//	p, err := NewFromConfig(Config{
//		Source:         header + script + footer,
//		TagOnException: "_js_exception",
//	}, nil)
//	if err != nil {
//		t.Fatal(err)
//	}
//
//	const goroutines = 10
//	ctx, cancel := context.WithCancel(context.Background())
//	defer cancel()
//
//	var wg sync.WaitGroup
//	wg.Add(goroutines)
//	for i := 0; i < goroutines; i++ {
//		go func() {
//			defer wg.Done()
//			for ctx.Err() == nil {
//				evt := &beat.Event{
//					Fields: common.MapStr{
//						"host": common.MapStr{"name": "computer"},
//					},
//				}
//				_, err := p.Run(evt)
//				assert.NoError(t, err)
//			}
//		}()
//	}
//
//	time.AfterFunc(time.Second, cancel)
//	wg.Wait()
//}
